// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

// 防止头文件重复包含

#include "InputModifiers.h"
#include "UObject/UnrealType.h"

// 包含所需头文件：
// - InputModifiers: 输入修改器基类
// - UnrealType: UE类型系统

#include "LyraInputModifiers.generated.h"

// UE代码生成头文件

struct FInputActionValue;
class FProperty;
class UEnhancedPlayerInput;
class ULyraAimSensitivityData;
class UObject;

// 前向声明

/** 
* 基于SharedUserSettings中的double属性缩放输入
*/
UCLASS(NotBlueprintable, MinimalAPI, meta = (DisplayName = "Setting Based Scalar"))
class ULyraSettingBasedScalar : public UInputModifier
{
	GENERATED_BODY()

public:
	/** 用于钳制X轴值的属性名称 */
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category=Settings)
	FName XAxisScalarSettingName = NAME_None;

	/** 用于钳制Y轴值的属性名称 */
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category=Settings)
	FName YAxisScalarSettingName = NAME_None;

	/** 用于钳制Z轴值的属性名称 */
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category=Settings)
	FName ZAxisScalarSettingName = NAME_None;
	
	/** 设置每个轴的最大值钳制 */
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category=Settings)
	FVector MaxValueClamp = FVector(10.0, 10.0, 10.0);
	
	/** 设置每个轴的最小值钳制 */
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category=Settings)
	FVector MinValueClamp = FVector::ZeroVector;

protected:
	// 实现输入修改的核心函数
	virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override;

	/** 属性缓存，避免每帧查找属性 */
	TArray<const FProperty*> PropertyCache;
};

/** 表示死区应用于哪个摇杆 */
UENUM()
enum class EDeadzoneStick : uint8
{
	/** 移动摇杆的死区 */
	MoveStick = 0,
	/** 视角摇杆的死区 */
	LookStick = 1,
};

/**
 * 死区输入修改器，其阈值由Lyra共享游戏设置驱动
 */
UCLASS(NotBlueprintable, MinimalAPI, meta = (DisplayName = "Lyra Settings Driven Dead Zone"))
class ULyraInputModifierDeadZone : public UInputModifier
{
	GENERATED_BODY()

public:
	// 死区类型
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category=Settings, Config)
	EDeadZoneType Type = EDeadZoneType::Radial;
	
	// 输入被钳制到1的上限阈值
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category=Settings, Config)
	float UpperThreshold = 1.0f;

	/** 此死区应用于哪个摇杆，控制计算死区时使用哪个设置 */
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category=Settings, Config)
	EDeadzoneStick DeadzoneStick = EDeadzoneStick::MoveStick;

protected:
	virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override;

	// 可视化颜色
	virtual FLinearColor GetVisualizationColor_Implementation(FInputActionValue SampleValue, FInputActionValue FinalValue) const override;
};

/** 瞄准灵敏度的类型 */
UENUM()
enum class ELyraTargetingType : uint8
{
	/** 正常视角移动时应用的灵敏度 */
	Normal = 0,
	/** 瞄准时应用的灵敏度 */
	ADS = 1,
};

/** 基于Lyra共享游戏设置中的当前游戏手柄设置应用标量修改器 */
UCLASS(NotBlueprintable, MinimalAPI, meta = (DisplayName = "Lyra Gamepad Sensitivity"))
class ULyraInputModifierGamepadSensitivity : public UInputModifier
{
	GENERATED_BODY()
public:
	/** 此灵敏度使用的瞄准类型 */
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category=Settings, Config)
	ELyraTargetingType TargetingType = ELyraTargetingType::Normal;

	/** 提供灵敏度标量值的数据资产 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AssetBundles="Client,Server"))
	TObjectPtr<const ULyraAimSensitivityData> SensitivityLevelTable;

protected:
	virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override;
};

/** 基于Lyra共享游戏设置中的设置应用轴值反转 */
UCLASS(NotBlueprintable, MinimalAPI, meta = (DisplayName = "Lyra Aim Inversion Setting"))
class ULyraInputModifierAimInversion : public UInputModifier
{
	GENERATED_BODY()
	
protected:
	virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override;	
};